package cn.ug.activity.service.impl;

import cn.ug.activity.bean.*;
import cn.ug.activity.mapper.CouponChannelMapper;
import cn.ug.activity.mapper.CouponMemberMapper;
import cn.ug.activity.mapper.CouponRepertoryMapper;
import cn.ug.activity.mapper.MemberInvestmentRewardsMapper;
import cn.ug.activity.mapper.entity.CouponMember;
import cn.ug.activity.mapper.entity.CouponRepertory;
import cn.ug.activity.service.CouponMemberService;
import cn.ug.bean.base.SerializeObject;
import cn.ug.bean.type.ResultType;
import cn.ug.config.AplicationResourceProperties;
import cn.ug.core.ensure.Ensure;
import cn.ug.enums.CouponTriggerEnum;
import cn.ug.feign.MemberAccountService;
import cn.ug.feign.MemberUserService;
import cn.ug.member.bean.MemberDetailBean;
import cn.ug.member.bean.response.MemberUserBean;
import cn.ug.msg.bean.status.CommonConstants;
import cn.ug.msg.mq.Msg;
import cn.ug.service.impl.BaseServiceImpl;
import cn.ug.util.UF;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

import static cn.ug.config.QueueName.QUEUE_MSG_SEND;
import static cn.ug.util.ConstantUtil.*;

@Service
public class CouponMemberServiceImpl extends BaseServiceImpl implements CouponMemberService {
    @Autowired
    private CouponMemberMapper couponMemberMapper;
    @Autowired
    private MemberUserService memberUserService;
    @Autowired
    private MemberInvestmentRewardsMapper memberInvestmentRewardsMapper;
    @Autowired
    private CouponRepertoryMapper couponRepertoryMapper;
    @Autowired
    protected AplicationResourceProperties properties;
    @Autowired
    private MemberAccountService memberAccountService;
    @Autowired
    private AmqpTemplate amqpTemplate;
    @Autowired
    private CouponChannelMapper couponChannelMapper;
    private static Logger logger = LoggerFactory.getLogger(CouponMemberServiceImpl.class);

    @Override
    public List<GiveOutFutureValueBean> listTicketFutureValueStatistics(String startDate, String endDate, List<String> channelIds) {
        List<GiveOutFutureValueBean> result = new ArrayList<GiveOutFutureValueBean>();
        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            SimpleDateFormat dateFormat = new SimpleDateFormat(NORMAL_DATE_FORMAT);
            Calendar futureCalendar = Calendar.getInstance();
            try {
                Date endDatetime = dateFormat.parse(endDate);
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(endDatetime);
                futureCalendar.setTime(dateFormat.parse(endDate));
                futureCalendar.add(Calendar.DAY_OF_YEAR, 30);
                for(;;) {
                    GiveOutFutureValueBean bean = new GiveOutFutureValueBean();
                    bean.setTime(dateFormat.format(calendar.getTime()));
                    result.add(bean);
                    if (StringUtils.equals(startDate, dateFormat.format(calendar.getTime()))) {
                        break;
                    }
                    calendar.add(Calendar.DAY_OF_YEAR, -1);
                }
            } catch (ParseException e) {
                e.printStackTrace();
            }
            String futureEndDate = dateFormat.format(futureCalendar.getTime());
            List<GiveOutFutureValueBean> futureResult = couponMemberMapper.listTicketFutureValueStatistics(startDate, futureEndDate, channelIds);

            for (GiveOutFutureValueBean bean : result) {
                if (futureResult != null && futureResult.size() > 0) {
                    double oneDayAmount = 0;
                    double sevenDayAmount = 0;
                    double thirtyDayAmount = 0;
                    List<String> futureSevenTime = new ArrayList<String>();
                    List<String> futureThirtyTime = new ArrayList<String>();
                    try {
                        Date time = dateFormat.parse(bean.getTime());
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTime(time);
                        int index = 0;
                        for(;;) {
                            if (index < 7) {
                                futureSevenTime.add(dateFormat.format(calendar.getTime()));
                            }
                            if (index < 30) {
                                futureThirtyTime.add(dateFormat.format(calendar.getTime()));
                            } else {
                                break;
                            }
                            calendar.add(Calendar.DAY_OF_YEAR, 1);
                            index++;
                        }
                    } catch (ParseException e) {
                        e.printStackTrace();
                    }
                    for (GiveOutFutureValueBean futureBean : futureResult) {
                        if (futureBean.getOneDayAmount() == null) {
                            continue;
                        }
                        if (StringUtils.equals(futureBean.getTime(), bean.getTime())) {
                            oneDayAmount = futureBean.getOneDayAmount().setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
                        }
                        if (futureSevenTime.contains(futureBean.getTime())) {
                            sevenDayAmount += futureBean.getOneDayAmount().setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
                        }
                        if (futureThirtyTime.contains(futureBean.getTime())) {
                            thirtyDayAmount += futureBean.getOneDayAmount().setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
                        }
                    }
                    bean.setOneDayAmount(new BigDecimal(oneDayAmount).setScale(2,BigDecimal.ROUND_HALF_UP));
                    bean.setSevenDayAmount(new BigDecimal(sevenDayAmount).setScale(2,BigDecimal.ROUND_HALF_UP));
                    bean.setThirtyDayAmount(new BigDecimal(thirtyDayAmount).setScale(2,BigDecimal.ROUND_HALF_UP));
                }
            }
            for (GiveOutFutureValueBean bean : result) {
                if (bean.getOneDayAmount() == null) {
                    bean.setOneDayAmount(BigDecimal.ZERO);
                }
                if (bean.getSevenDayAmount() == null) {
                    bean.setSevenDayAmount(BigDecimal.ZERO);
                }
                if (bean.getThirtyDayAmount() == null) {
                    bean.setThirtyDayAmount(BigDecimal.ZERO);
                }
            }
        }
        return result;
    }

    @Override
    public MemberDetailBean getUsableCouponInfo(String memberId) {
        if (StringUtils.isNotBlank(memberId)) {
            return couponMemberMapper.selectUsableCouponInfo(memberId);
        }
        return null;
    }

    @Override
    public List<CouponMemberBean> queryForCouponList(String memberId, List<Integer> couponIds) {
        if (StringUtils.isNotBlank(memberId) && couponIds != null && couponIds.size() > 0) {
            return couponMemberMapper.queryForCouponList(memberId, couponIds);
        }
        return null;
    }

    @Override
    public Map queryCouponStatistics(Map<String, Object> param) {
        return couponMemberMapper.queryCouponStatistics(param);
    }

    @Override
    public List<GiveOutAverageValueBean> listAvgValueStatistics(int type, int timeType, String startDate, String endDate, List<String> channelIds) {
        List<GiveOutAverageValueBean> result = new ArrayList<GiveOutAverageValueBean>();
        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            if (timeType == 1) {
                SimpleDateFormat dateFormat = new SimpleDateFormat(NORMAL_DATE_FORMAT);
                try {
                    Date endDatetime = dateFormat.parse(endDate);
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(endDatetime);
                    for(;;) {
                        GiveOutAverageValueBean bean = new GiveOutAverageValueBean();
                        bean.setTime(dateFormat.format(calendar.getTime()));
                        result.add(bean);
                        if (StringUtils.equals(startDate, dateFormat.format(calendar.getTime()))) {
                            break;
                        }
                        calendar.add(Calendar.DAY_OF_YEAR, -1);
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            } else if (timeType == 2) {
                SimpleDateFormat monthFormat = new SimpleDateFormat(NORMAL_MONTH_FORMAT);
                try {
                    Date endDatetime = monthFormat.parse(endDate);
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(endDatetime);
                    Set<String> info = new HashSet<String>();
                    for(;;) {
                        GiveOutAverageValueBean bean = new GiveOutAverageValueBean();
                        String value = monthFormat.format(calendar.getTime());
                        if (!info.contains(value)) {
                            info.add(value);
                            bean.setTime(monthFormat.format(calendar.getTime()));
                            result.add(bean);
                        }
                        if (StringUtils.startsWith(startDate, monthFormat.format(calendar.getTime()))) {
                            break;
                        }
                        calendar.add(Calendar.MONTH, -1);
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            } else if (timeType == 3) {
                SimpleDateFormat dateFormat = new SimpleDateFormat(NORMAL_DATE_FORMAT);
                try {
                    Date endDatetime = dateFormat.parse(endDate);
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(endDatetime);
                    int week = calendar.get(Calendar.DAY_OF_WEEK);
                    if (week == 1) {
                        calendar.add(Calendar.DAY_OF_YEAR, -1);
                    }
                    Set<String> info = new HashSet<String>();
                    SimpleDateFormat weekFormat = new SimpleDateFormat("yyyy-ww");
                    for(;;) {
                        GiveOutAverageValueBean bean = new GiveOutAverageValueBean();
                        String value = weekFormat.format(calendar.getTime());
                        if (!info.contains(value)) {
                            info.add(value);
                            bean.setTime(value);
                            result.add(bean);
                        }
                        if (StringUtils.startsWith(startDate, dateFormat.format(calendar.getTime()))) {
                            break;
                        }
                        calendar.add(Calendar.DAY_OF_YEAR, -1);
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            List<GiveOutAverageValueBean> avgResult = null;
            if (type == 1) {
                avgResult = couponMemberMapper.listCouponAvgValueStatistics(timeType, startDate, endDate, channelIds);
            } else if (type == 2) {
                avgResult = couponMemberMapper.listTicketAvgValueStatistics(timeType, startDate, endDate, channelIds);
            } else if (type == 3) {
                avgResult = memberInvestmentRewardsMapper.listRewardsAvgValueStatistics(timeType, startDate, endDate, channelIds);
            } else {
                return null;
            }
            for (GiveOutAverageValueBean bean : result) {
                if (avgResult != null && avgResult.size() > 0) {
                    for (GiveOutAverageValueBean averageValueBean : avgResult) {
                        if (StringUtils.equals(bean.getTime(), averageValueBean.getTime()) && averageValueBean.getSingleAmount() != null) {
                            bean.setSingleAmount(averageValueBean.getSingleAmount().setScale(2,BigDecimal.ROUND_HALF_UP));
                        }
                        if (StringUtils.equals(bean.getTime(), averageValueBean.getTime()) && averageValueBean.getEveryoneAmount() != null) {
                            bean.setEveryoneAmount(averageValueBean.getEveryoneAmount().setScale(2,BigDecimal.ROUND_HALF_UP));
                        }
                    }
                }
            }
            for (GiveOutAverageValueBean bean : result) {
                if (bean.getEveryoneAmount() == null) {
                    bean.setEveryoneAmount(BigDecimal.ZERO);
                }
                if (bean.getSingleAmount() == null) {
                    bean.setSingleAmount(BigDecimal.ZERO);
                }
            }
            if (timeType == 3) {
                for (GiveOutAverageValueBean bean : result) {
                    String[] arrs = StringUtils.split(bean.getTime(), MINUS);
                    bean.setTime(UF.getWeekInterval(Integer.parseInt(arrs[0]), Integer.parseInt(arrs[1])));
                }
                result.get(0).setTime(StringUtils.split(result.get(0).getTime(), WAVE)[0] + WAVE + endDate);
                result.get(result.size()-1).setTime(startDate+WAVE+StringUtils.split(result.get(result.size()-1).getTime(), WAVE)[1]);
            }
        }
        return result;
    }

    @Override
    public List<GiveOutBean> listGrantStatistics(int timeType, String startDate, String endDate, List<String> channelIds) {
        List<GiveOutBean> result = new ArrayList<GiveOutBean>();
        if (StringUtils.isNotBlank(startDate) && StringUtils.isNotBlank(endDate)) {
            if (timeType == 1) {
                SimpleDateFormat dateFormat = new SimpleDateFormat(NORMAL_DATE_FORMAT);
                try {
                    Date endDatetime = dateFormat.parse(endDate);
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(endDatetime);
                    for(;;) {
                        GiveOutBean bean = new GiveOutBean();
                        bean.setTime(dateFormat.format(calendar.getTime()));
                        result.add(bean);
                        if (StringUtils.equals(startDate, dateFormat.format(calendar.getTime()))) {
                            break;
                        }
                        calendar.add(Calendar.DAY_OF_YEAR, -1);
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            } else if (timeType == 2) {
                SimpleDateFormat monthFormat = new SimpleDateFormat(NORMAL_MONTH_FORMAT);
                try {
                    Date endDatetime = monthFormat.parse(endDate);
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(endDatetime);
                    Set<String> info = new HashSet<String>();
                    for(;;) {
                        GiveOutBean bean = new GiveOutBean();
                        String value = monthFormat.format(calendar.getTime());
                        if (!info.contains(value)) {
                            info.add(value);
                            bean.setTime(monthFormat.format(calendar.getTime()));
                            result.add(bean);
                        }
                        if (StringUtils.startsWith(startDate, monthFormat.format(calendar.getTime()))) {
                            break;
                        }
                        calendar.add(Calendar.MONTH, -1);
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            } else if (timeType == 3) {
                SimpleDateFormat dateFormat = new SimpleDateFormat(NORMAL_DATE_FORMAT);
                try {
                    Date endDatetime = dateFormat.parse(endDate);
                    Calendar calendar = Calendar.getInstance();
                    calendar.setTime(endDatetime);
                    int week = calendar.get(Calendar.DAY_OF_WEEK);
                    if (week == 1) {
                        calendar.add(Calendar.DAY_OF_YEAR, -1);
                    }
                    Set<String> info = new HashSet<String>();
                    SimpleDateFormat weekFormat = new SimpleDateFormat("yyyy-ww");
                    for(;;) {
                        GiveOutBean bean = new GiveOutBean();
                        String value = weekFormat.format(calendar.getTime());
                        if (!info.contains(value)) {
                            info.add(value);
                            //String[] arrs = StringUtils.split(value, MINUS);
                            bean.setTime(value);
                            result.add(bean);
                        }
                        if (StringUtils.startsWith(startDate, dateFormat.format(calendar.getTime()))) {
                            break;
                        }
                        calendar.add(Calendar.DAY_OF_YEAR, -1);
                    }
                } catch (ParseException e) {
                    e.printStackTrace();
                }
            }
            List<GiveOutBean> couponResult = couponMemberMapper.listCouponGrantStatistics(timeType, startDate, endDate, channelIds);
            List<GiveOutBean> ticketResult = couponMemberMapper.listTicketGrantStatistics(timeType, startDate, endDate, channelIds);
            List<GiveOutBean> rewardsResult = memberInvestmentRewardsMapper.listRewardsGrantStatistics(timeType, startDate, endDate, channelIds);
            double totalCouponAmount = 0;
            double totalTicketAmount = 0;
            double totalRewardsAmount = 0;
            if (couponResult != null && couponResult.size() > 0) {
                for (GiveOutBean bean : couponResult) {
                    if (bean.getCouponAmount() != null) {
                        totalCouponAmount += bean.getCouponAmount().setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
                    }
                }
            }
            if (ticketResult != null && ticketResult.size() > 0) {
                for (GiveOutBean bean : ticketResult) {
                    if (bean.getTicketAmount() != null) {
                        totalTicketAmount += bean.getTicketAmount().setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
                    }
                }
            }
            if (rewardsResult != null && rewardsResult.size() > 0) {
                for (GiveOutBean bean : rewardsResult) {
                    if (bean.getRewardAmount() != null) {
                        totalRewardsAmount += bean.getRewardAmount().setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();
                    }
                }
            }
            for (GiveOutBean bean : result) {
                bean.setTotalCouponAmount(new BigDecimal(totalCouponAmount).setScale(2,BigDecimal.ROUND_HALF_UP));
                bean.setTotalTicketAmount(new BigDecimal(totalTicketAmount).setScale(2,BigDecimal.ROUND_HALF_UP));
                bean.setTotalRewardAmount(new BigDecimal(totalRewardsAmount).setScale(2,BigDecimal.ROUND_HALF_UP));
                if (couponResult != null && couponResult.size() > 0) {
                    for (GiveOutBean couponBean : couponResult) {
                        if (StringUtils.equals(bean.getTime(), couponBean.getTime()) && couponBean.getCouponAmount() != null) {
                            bean.setCouponAmount(couponBean.getCouponAmount().setScale(2,BigDecimal.ROUND_HALF_UP));
                        }
                    }
                }
                if (ticketResult != null && ticketResult.size() > 0) {
                    for (GiveOutBean ticketBean : ticketResult) {
                        if (StringUtils.equals(bean.getTime(), ticketBean.getTime()) && ticketBean.getTicketAmount() != null) {
                            bean.setTicketAmount(ticketBean.getTicketAmount().setScale(2,BigDecimal.ROUND_HALF_UP));
                        }
                    }
                }
                if (rewardsResult != null && rewardsResult.size() > 0) {
                    for (GiveOutBean rewardsBean : rewardsResult) {
                        if (StringUtils.equals(bean.getTime(), rewardsBean.getTime()) && rewardsBean.getRewardAmount() != null) {
                            bean.setRewardAmount(rewardsBean.getRewardAmount().setScale(2,BigDecimal.ROUND_HALF_UP));
                        }
                    }
                }
            }
            for (GiveOutBean bean : result) {
                if (bean.getRewardAmount() == null) {
                    bean.setRewardAmount(BigDecimal.ZERO);
                }
                if (bean.getTicketAmount() == null) {
                    bean.setTicketAmount(BigDecimal.ZERO);
                }
                if (bean.getCouponAmount() == null) {
                    bean.setCouponAmount(BigDecimal.ZERO);
                }
            }
            if (timeType == 3) {
                for (GiveOutBean bean : result) {
                    String[] arrs = StringUtils.split(bean.getTime(), MINUS);
                    bean.setTime(UF.getWeekInterval(Integer.parseInt(arrs[0]), Integer.parseInt(arrs[1])));
                }
                result.get(0).setTime(StringUtils.split(result.get(0).getTime(), WAVE)[0] + WAVE + endDate);
                result.get(result.size()-1).setTime(startDate+WAVE+StringUtils.split(result.get(result.size()-1).getTime(), WAVE)[1]);
            }
        }
        return result;
    }

    @Override
    public boolean save(CouponMember couponMember) {
        if (couponMember != null) {
            if (couponMember.getId() < 1) {
                couponMember.setAddTime(UF.getFormatDateTime(LocalDateTime.now()));
                return couponMemberMapper.insert(couponMember) > 0 ? true : false;
            } else {
                couponMember.setUsedTime(UF.getFormatDateTime(LocalDateTime.now()));
                return couponMemberMapper.update(couponMember) > 0 ? true : false;
            }
        }
        return false;
    }

    @Override
    public boolean donate(CouponMember couponMember) {
        if (couponMember != null && couponMember.getId() > 0) {
            return couponMemberMapper.update(couponMember) > 0 ? true : false;
        }
        return false;
    }

    @Override
    public CouponMember get(String id) {
        if (StringUtils.isNotBlank(id)) {
            return couponMemberMapper.findById(id);
        }
        return null;
    }

    @Transactional
    @Override
    public double giveCoupon(String userId, String couponId) {
        if (StringUtils.isBlank(userId)) {
            return 0;
        }
        SerializeObject<MemberUserBean> userBean = memberUserService.findById(userId);
        if(null == userBean || userBean.getCode() != ResultType.NORMAL || userBean.getData() == null) {
            return 0;
        }
        MemberUserBean user = userBean.getData();
        if (StringUtils.isBlank(couponId)) {
            return 0;
        }
        CouponRepertory coupon = couponRepertoryMapper.findById(couponId);
        if (coupon == null) {
            return 0;
        }
        CouponMember couponMember = new CouponMember();
        couponMember.setMemberId(user.getId());
        couponMember.setAddTime(UF.getFormatDateTime(LocalDateTime.now()));
        couponMember.setCouponId(coupon.getId());
        if (couponMemberMapper.insert(couponMember) > 0) {
            return coupon.getDiscountAmount();
        } else {
            return 0;
        }
    }

    @Transactional
    @Override
    public boolean receiveCoupon(String memberId, String couponId) {
        if (StringUtils.isBlank(memberId)) {
            return false;
        }
        SerializeObject<MemberUserBean> userBean = memberUserService.findById(memberId);
        if(null == userBean || userBean.getCode() != ResultType.NORMAL || userBean.getData() == null) {
            return false;
        }
        MemberUserBean user = userBean.getData();
        if (StringUtils.isBlank(couponId)) {
            return false;
        }
        CouponRepertory coupon = couponRepertoryMapper.findById(couponId);
        if (coupon == null) {
            return false;
        }
        List<Integer> couponIds = new ArrayList<Integer>();
        couponIds.add(Integer.parseInt(couponId));
        List<CouponMemberBean> beans = couponMemberMapper.queryForCouponList(memberId, couponIds);
        if (beans != null && beans.size() > 0) {
            Ensure.that(0).isLt(1, "22000146");
        }
        CouponMember couponMember = new CouponMember();
        couponMember.setMemberId(user.getId());
        couponMember.setAddTime(UF.getFormatDateTime(LocalDateTime.now()));
        couponMember.setCouponId(coupon.getId());
        return couponMemberMapper.insert(couponMember) > 0 ? true : false;
    }

    @Override
    public int countCoupons(String couponId) {
        if (StringUtils.isNotBlank(couponId)) {
            return couponMemberMapper.queryCouponsForCountByCouponId(couponId);
        }
        return 0;
    }

    @Override
    public List<CouponMemberBean> listRecords(String memberId, int type) {
        if (StringUtils.isNotBlank(memberId)) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("memberId", memberId);
            params.put("type", type);
            return couponMemberMapper.queryForList(params);
        }
        return null;
    }

    @Override
    public CouponMemberBean getCouponMemberBean(String id) {
        if (StringUtils.isNotBlank(id)) {
            return couponMemberMapper.findBeanById(id);
        }
        return null;
    }

    @Override
    public CouponMemberBean selectById(int couponMemberId) {
        if (couponMemberId > 0) {
            return couponMemberMapper.selectById(couponMemberId);
        }
        return null;
    }

    @Override
    public List<CouponStatisticsBean> listCouponStatistics(int type, String mobile, String name, int startAccumulationNum, int endAccumulationNum, int startUsedNum, int endUsedNum, String order,
                                                           String sort, int offset, int size,BigDecimal startUsedRate,BigDecimal endUsedRate,BigDecimal startDiscountAwardAmount,BigDecimal endDiscountAwardAmount) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("type", type);
        if (StringUtils.isNotBlank(name)) {
            param.put("name", name);
        }
        if (StringUtils.isNotBlank(mobile)) {
            param.put("mobile", mobile);
        }
        param.put("startAccumulationNum", startAccumulationNum);
        param.put("endAccumulationNum", endAccumulationNum);
        param.put("startUsedNum", startUsedNum);
        param.put("endUsedNum", endUsedNum);
        param.put("startUsedRate", startUsedRate);
        param.put("endUsedRate", endUsedRate);
        param.put("startDiscountAwardAmount",startDiscountAwardAmount);
        param.put("endDiscountAwardAmount", endDiscountAwardAmount);
        List<String> orders = Arrays.asList("couponNum", "usedNum", "invalidationNum", "usablenessNum","totalAwardAmount","usedRate","usedGram","discountAwardAmount");
        if (orders.contains(order)) {
            param.put("order", order);
            param.put("sort", "desc");
            if (StringUtils.equalsIgnoreCase(sort, "asc") || StringUtils.equalsIgnoreCase(sort, "desc")) {
                param.put("sort", sort);
            }
        }
        param.put("offset", offset);
        param.put("size", size);
        return couponMemberMapper.listCouponStatistics(param);
    }

    @Override
    public int countCouponStatistics(int type, String mobile, String name, int startAccumulationNum, int endAccumulationNum, int startUsedNum, int endUsedNum,
                                     BigDecimal startUsedRate,BigDecimal endUsedRate,BigDecimal startDiscountAwardAmount,BigDecimal endDiscountAwardAmount) {
        Map<String, Object> param = new HashMap<String, Object>();
        param.put("type", type);
        if (StringUtils.isNotBlank(name)) {
            param.put("name", name);
        }
        if (StringUtils.isNotBlank(mobile)) {
            param.put("mobile", mobile);
        }
        param.put("startAccumulationNum", startAccumulationNum);
        param.put("endAccumulationNum", endAccumulationNum);
        param.put("startUsedNum", startUsedNum);
        param.put("endUsedNum", endUsedNum);
        param.put("startUsedRate", startUsedRate);
        param.put("endUsedRate", endUsedRate);
        param.put("startDiscountAwardAmount",startDiscountAwardAmount);
        param.put("endDiscountAwardAmount", endDiscountAwardAmount);
        return couponMemberMapper.countCouponStatistics(param);
    }

    @Override
    public List<CouponStatisticsBean> listInterestTicketStatistics(String startDate, String endDate, String mobile, int offset, int size) {
        Map<String, Object> param = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(startDate)) {
            param.put("startDate", startDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            param.put("endDate", endDate);
        }
        if (StringUtils.isNotBlank(mobile)) {
            param.put("mobile", mobile);
        }
        param.put("offset", offset);
        param.put("size", size);
        return couponMemberMapper.listInterestTicketStatistics(param);
    }

    @Override
    public int countInterestTicketStatistics(String startDate, String endDate, String mobile) {
        Map<String, Object> param = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(startDate)) {
            param.put("startDate", startDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            param.put("endDate", endDate);
        }
        if (StringUtils.isNotBlank(mobile)) {
            param.put("mobile", mobile);
        }
        return couponMemberMapper.countInterestTicketStatistics(param);
    }

    @Override
    public List<CouponMemberItemBean> listCoupons(int type, int status, String memberId, String mobile, String name, String startSendDate, String endSendDate, String startIndateTime, String endIndateTime, String order, String sort, int offset, int size,
                                                  String startUsedDate,String endUedDate,BigDecimal startAmount,BigDecimal endAmount) {
        Map<String, Object> param = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(startSendDate)) {
            param.put("startSendDate", startSendDate);
        }
        if (StringUtils.isNotBlank(endSendDate)) {
            param.put("endSendDate", endSendDate);
        }
        if (StringUtils.isNotBlank(startIndateTime)) {
            param.put("startIndateTime", startIndateTime);
        }
        if (StringUtils.isNotBlank(endIndateTime)) {
            param.put("endIndateTime", endIndateTime);
        }
        if (StringUtils.isNotBlank(memberId)) {
            param.put("memberId", memberId);
        }
        if (StringUtils.isNotBlank(mobile)) {
            param.put("mobile", mobile);
        }
        if (StringUtils.isNotBlank(name)) {
            param.put("name", name);
        }

        if (StringUtils.isNotBlank(startUsedDate)){
            param.put("startUsedDate", startUsedDate);
        }

        if (StringUtils.isNotBlank(endUedDate)){
            param.put("endUedDate", endUedDate);
        }
        param.put("startAmount", startAmount);
        param.put("endAmount", endAmount);

        param.put("type", type);
        param.put("status", status);
        List<String> orders = Arrays.asList("sendTime", "indateTime", "amount", "usedTime", "yearIncome","discountAmount","raiseYearIncome","totalGram","orderGram");
        if (orders.contains(order)) {
            param.put("order", order);
            param.put("sort", "desc");
            if (StringUtils.equalsIgnoreCase(sort, "asc") || StringUtils.equalsIgnoreCase(sort, "desc")) {
                param.put("sort", sort);
            }
        }
        param.put("offset", offset);
        param.put("size", size);
        return couponMemberMapper.queryCouponsForList(param);
    }

    @Override
    public int countCoupons(int type, int status, String memberId, String mobile, String name, String startSendDate, String endSendDate, String startIndateTime, String endIndateTime,
                            String startUsedDate,String endUedDate,BigDecimal startAmount,BigDecimal endAmount) {
        Map<String, Object> param = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(startSendDate)) {
            param.put("startSendDate", startSendDate);
        }
        if (StringUtils.isNotBlank(endSendDate)) {
            param.put("endSendDate", endSendDate);
        }
        if (StringUtils.isNotBlank(startIndateTime)) {
            param.put("startIndateTime", startIndateTime);
        }
        if (StringUtils.isNotBlank(endIndateTime)) {
            param.put("endIndateTime", endIndateTime);
        }
        if (StringUtils.isNotBlank(memberId)) {
            param.put("memberId", memberId);
        }
        if (StringUtils.isNotBlank(mobile)) {
            param.put("mobile", mobile);
        }
        if (StringUtils.isNotBlank(name)) {
            param.put("name", name);
        }

        if (StringUtils.isNotBlank(startUsedDate)) {
            param.put("startUsedDate", startUsedDate);
        }
        if (StringUtils.isNotBlank(endUedDate)) {
            param.put("endUedDate",endUedDate );
        }
        param.put("startAmount", startAmount);
        param.put("endAmount", endAmount);

        param.put("type", type);
        param.put("status", status);
        return couponMemberMapper.queryCouponsForCount(param);
    }

    @Override
    public boolean save(List<CouponMember> couponMembers) {
        if (couponMembers != null && couponMembers.size() > 0) {
            return couponMemberMapper.insertInBatch(couponMembers) > 0 ? true : false;
        }
        return false;
    }

    @Override
    public List<DonationCouponBean> listFinanceCoupons(int type, String startDate, String endDate, int offset, int size) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("type", type);
        params.put("offset", offset);
        params.put("size", size);
        if (StringUtils.isNotBlank(startDate)) {
            params.put("startDate", startDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            params.put("endDate", endDate);
        }
        return couponMemberMapper.queryCouponsForFinanceList(params);
    }

    @Override
    public int countFinanceCoupons(int type, String startDate, String endDate) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("type", type);
        if (StringUtils.isNotBlank(startDate)) {
            params.put("startDate", startDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            params.put("endDate", endDate);
        }
        return couponMemberMapper.queryCouponsForFinanceCount(params);
    }

    @Override
    public List<DonationCouponRecordBean> listFinanceRecordCoupons(String grantTime, int type, BigDecimal startAmount, BigDecimal endAmount, String mobile, String name, int offset, int size) {
        if (StringUtils.isNotBlank(grantTime)) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("grantTime", grantTime);
            params.put("type", type);
            if (startAmount == null) {
                params.put("startAmount", -1);
            } else {
                params.put("startAmount", startAmount.doubleValue());
            }
            if (endAmount == null) {
                params.put("endAmount", -1);
            } else {
                params.put("endAmount", endAmount.doubleValue());
            }
            if (StringUtils.isNotBlank(mobile)) {
                params.put("mobile", mobile);
            }
            if (StringUtils.isNotBlank(name)) {
                params.put("name", name);
            }
            params.put("offset", offset);
            params.put("size", size);
            return couponMemberMapper.queryCouponsForFinanceRecordList(params);
        }
        return null;

    }

    @Override
    public int countFinanceRecordCoupons(String grantTime, int type, BigDecimal startAmount, BigDecimal endAmount, String mobile, String name) {
        if (StringUtils.isNotBlank(grantTime)) {
            Map<String, Object> params = new HashMap<String, Object>();
            params.put("grantTime", grantTime);
            params.put("type", type);
            if (startAmount == null) {
                params.put("startAmount", -1);
            } else {
                params.put("startAmount", startAmount.doubleValue());
            }
            if (endAmount == null) {
                params.put("endAmount", -1);
            } else {
                params.put("endAmount", endAmount.doubleValue());
            }
            if (StringUtils.isNotBlank(mobile)) {
                params.put("mobile", mobile);
            }
            if (StringUtils.isNotBlank(name)) {
                params.put("name", name);
            }
            return couponMemberMapper.queryCouponsForFinanceRecordCount(params);
        }
        return 0;
    }

    @Override
    public List<MemberDonationCouponBean> listFinanceRecordCoupons(String grantTime, int type, String memberId, String startDate, String endDate, int offset, int size) {
        Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(grantTime)) {
            params.put("grantTime", grantTime);
        }
        if (StringUtils.isNotBlank(startDate)) {
            params.put("startDate", startDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            params.put("endDate", endDate);
        }
        if (StringUtils.isNotBlank(memberId)) {
            params.put("memberId", memberId);
        }
        params.put("type", type);
        params.put("offset", offset);
        params.put("size", size);
        return couponMemberMapper.queryForFinanceRecordListByMemberId(params);
    }

    @Override
    public int countFinanceRecordCoupons(String grantTime, int type, String memberId, String startDate, String endDate) {
        Map<String, Object> params = new HashMap<String, Object>();
        if (StringUtils.isNotBlank(memberId)) {
            params.put("memberId", memberId);
        }
        if (StringUtils.isNotBlank(grantTime)) {
            params.put("grantTime", grantTime);
        }
        if (StringUtils.isNotBlank(startDate)) {
            params.put("startDate", startDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            params.put("endDate", endDate);
        }
        params.put("type", type);
        return couponMemberMapper.queryForFinanceRecordCountByMemberId(params);
    }

    @Transactional
    @Override
    public boolean giveCoupons(String userId, int trigger) {
        if (StringUtils.isBlank(userId)) {
            return false;
        }
        /*SerializeObject<MemberUserBean> userBean = memberUserService.findById(userId);
        if(null == userBean || userBean.getCode() != ResultType.NORMAL) {
            return false;
        }*/
        boolean result = true;
        List<CouponRepertory> couponRepertories = couponRepertoryMapper.queryUsableCoupons(0, -1, trigger);
        if (couponRepertories != null && couponRepertories.size() > 0) {
            int amount = 0;
            for (CouponRepertory couponRepertory : couponRepertories) {
                if (couponRepertory.getType() == 0) {
                    amount += couponRepertory.getDiscountAmount();
                }
            }
            List<CouponMember> coupons = wrapCoupons(couponRepertories, userId);
            if (coupons != null && coupons.size() > 0) {
                result = couponMemberMapper.insertInBatch(coupons) > 0 ? true : false;
                if (result && CouponTriggerEnum.REGISTER.getTrigger() == trigger && amount > 0) {
                    Msg msg = new Msg();
                    msg.setMemberId(userId);
                    msg.setType(CommonConstants.MsgType.REGISTER_WELFARE.getIndex());
                    Map<String, String> paramMap = new HashMap<>();
                    paramMap.put("content",String.valueOf(amount));
                    msg.setParamMap(paramMap);
                    amqpTemplate.convertAndSend(QUEUE_MSG_SEND, msg);
                }
            }
        }
        return result;
    }

    private List<CouponMember> wrapCoupons(List<CouponRepertory> regiserCoupons, String userId) {
        if (regiserCoupons != null && regiserCoupons.size() > 0) {
            List<CouponMember> couponMembers = new ArrayList<CouponMember>();
            for (CouponRepertory coupon : regiserCoupons) {
                CouponMember couponMember = new CouponMember();
                couponMember.setMemberId(userId);
                couponMember.setAddTime(UF.getFormatDateTime(LocalDateTime.now()));
                couponMember.setCouponId(coupon.getId());
                couponMembers.add(couponMember);
            }
            /*regiserCoupons.forEach(coupon -> {
                CouponMember couponMember = new CouponMember();
                couponMember.setMemberId(user.getId());
                couponMember.setAddTime(UF.getFormatDateTime(LocalDateTime.now()));
                couponMember.setCouponId(coupon.getId());
                couponMembers.add(couponMember);
            });*/
            return  couponMembers;
        }
        return null;
    }

}
